<?php
namespace restphp\common\exploitation\upload\controller;

use restphp\biz\RestErrorCode;
use restphp\common\exploitation\exception\ExploitationException;
use restphp\common\exploitation\upload\constant\RestUploadConstant;
use restphp\common\exploitation\upload\controller\vo\FileDeleteForm;
use restphp\core\RestCallAnyWhere;
use restphp\core\RestCallAnyWhereConstant;
use restphp\http\RestHttpRequest;
use restphp\http\RestHttpResponse;
use restphp\utils\RestStringUtils;
use restphp\utils\RestUUIDUtil;


/**
 * 表单上传.
 * Class FormUploaderController
 * @package restphp\common\exploitation\upload
 * @RequestMapping(value="/__upload/form")
 */
class FormUploaderController {
    /**
     * 表单单文件上传.
     * @throws ExploitationException
     * @RequestMapping(value="/single", method="POST")
     */
    public function formUploadSingle() {
        //总配置检查.
        if (!isset($GLOBALS[RestUploadConstant::UPLOAD_CONFIG_NAME])) {
            throw new ExploitationException(RestUploadConstant::UPLOAD_CONFIG_ERROR);
        }

        //一级配置检查.
        $arrConfig = $GLOBALS[RestUploadConstant::UPLOAD_CONFIG_NAME];
        if (!isset($arrConfig[RestUploadConstant::UPLOAD_CONFIG_NAME_COLUMN_FILE]) ||
            !isset($arrConfig[RestUploadConstant::UPLOAD_CONFIG_NAME_COLUMN_RIGHT]) ||
            !isset($arrConfig[RestUploadConstant::UPLOAD_CONFIG_NAME_RIGHT]) ||
            !isset($arrConfig[RestUploadConstant::UPLOAD_CONFIG_NAME_SAVE_ROOT]) ||
            !isset($arrConfig[RestUploadConstant::UPLOAD_CONFIG_NAME_VISIT_URI])) {
            throw new ExploitationException(RestUploadConstant::UPLOAD_CONFIG_ERROR);
        }
        $arrRightConfig = $arrConfig[RestUploadConstant::UPLOAD_CONFIG_NAME_RIGHT];
        /*if (!isset($arrRightConfig[RestUploadConstant::UPLOAD_CONFIG_NAME_RIGHT_SET_MEDIA])) {
            throw new ExploitationException(RestUploadConstant::UPLOAD_CONFIG_ERROR);
        }*/

        //权限目录配置检查
        $rightCode = RestHttpRequest::getRequest($arrConfig[RestUploadConstant::UPLOAD_CONFIG_NAME_COLUMN_RIGHT]);
        if (RestStringUtils::isBlank($rightCode)) {
            throw new ExploitationException(RestErrorCode::PARAM_ERROR);
        }
        if (!isset($arrRightConfig[$rightCode])) {
            throw new ExploitationException(RestUploadConstant::UPLOAD_CONFIG_ERROR_NOT_EXISTS_RIGHT);
        }
        //媒体类型检查
        $arrThisConfig = $arrRightConfig[$rightCode];
        if (!isset($arrThisConfig[RestUploadConstant::UPLOAD_CONFIG_NAME_RIGHT_SET_MEDIA])) {
            throw new ExploitationException(RestUploadConstant::UPLOAD_CONFIG_ERROR_MEDIA);
        };
        if (!isset($arrThisConfig[RestUploadConstant::UPLOAD_CONFIG_NAME_SIZE_MAX]) ||
            !isset($arrThisConfig[RestUploadConstant::UPLOAD_CONFIG_NAME_SIZE_MIN])) {
            throw new ExploitationException(RestUploadConstant::UPLOAD_CONFIG_ERROR_FILE_SIZE);
        }

        //上传文件检查
        if (empty($_FILES)) {
            throw new ExploitationException(RestUploadConstant::UPLOAD_CONFIG_ERROR_FILE_ERROR);
        }

        //上传文件检查
        if (!isset($_FILES[$arrConfig[RestUploadConstant::UPLOAD_CONFIG_NAME_COLUMN_FILE]])) {
            throw new ExploitationException(RestErrorCode::PARAM_ERROR);
        }
        //接受上传文件
        $arrFile = $_FILES[$arrConfig[RestUploadConstant::UPLOAD_CONFIG_NAME_COLUMN_FILE]];
        //媒体类型检查
        $arrAllMedia = $arrThisConfig[RestUploadConstant::UPLOAD_CONFIG_NAME_RIGHT_SET_MEDIA];
        if (!in_array("*", $arrAllMedia) && !in_array($arrFile['type'], $arrAllMedia)) {
            throw new ExploitationException(RestUploadConstant::UPLOAD_ERROR_MEDIA_NOT_SUPPORT);
        }
        //文件大小检查
        if (isset($arrThisConfig[RestUploadConstant::UPLOAD_CONFIG_NAME_SIZE_MAX])) {
            $maxSize = $arrThisConfig[RestUploadConstant::UPLOAD_CONFIG_NAME_SIZE_MAX] * 1000;
            if ($arrFile['size'] > $maxSize) {
                throw new ExploitationException(RestUploadConstant::UPLOAD_ERROR_FILE_SIZE_MAX, 400, array($arrFile['size']));
            }
        }
        if (isset($arrThisConfig[RestUploadConstant::UPLOAD_CONFIG_NAME_SIZE_MIN])) {
            $minSize = $arrThisConfig[RestUploadConstant::UPLOAD_CONFIG_NAME_SIZE_MIN] * 1000;
            if ($arrFile['size'] < $minSize) {
                throw new ExploitationException(RestUploadConstant::UPLOAD_ERROR_FILE_SIZE_MIN, 400, array($arrFile['size']));
            }
        }

        //获取保存的相对路径
        $rightCallConfig = $arrRightConfig[$rightCode];
        $strDir = DIRECTORY_SEPARATOR . $rightCode;
        //前置调用
        if (isset($rightCallConfig[RestUploadConstant::UPLOAD_CONFIG_NAME_BIZ_CALL_UPLOAD_BEFORE])) {
            $preCall = $rightCallConfig[RestUploadConstant::UPLOAD_CONFIG_NAME_BIZ_CALL_UPLOAD_BEFORE];
            $preCall[RestCallAnyWhere::PARAMETER_NAME_PARAMETERS] = $rightCode;
            $strDir = RestCallAnyWhere::call($preCall);
        };

        //保存文件
        $strFile = RestUUIDUtil::guid() . substr($arrFile['name'], strrpos($arrFile['name'], "."));
        $rootDir = $arrConfig[RestUploadConstant::UPLOAD_CONFIG_NAME_SAVE_ROOT];
        $strSaveDir = $rootDir . $strDir;
        $strSavePath = $strSaveDir . DIRECTORY_SEPARATOR . $strFile;

        //访问路径
        $startUri = $arrConfig[RestUploadConstant::UPLOAD_CONFIG_NAME_VISIT_URI];
        $strUrl = $startUri . "/" . $rightCode . "/" . $strFile;

        //保存文件
        rename($arrFile['tmp_name'], $strSavePath);

        $arrResult = array('url' => $strUrl, 'name' => $arrFile['name'], 'size' => $arrFile['size']);

        //后置任务
        if (isset($rightCallConfig[RestUploadConstant::UPLOAD_CONFIG_NAME_BIZ_CALL_UPLOAD_AFTER])) {
            $appendCall = $rightCallConfig[RestUploadConstant::UPLOAD_CONFIG_NAME_BIZ_CALL_UPLOAD_AFTER];
            $appendCall[RestCallAnyWhere::PARAMETER_NAME_PARAMETERS] = $arrResult;
            $arrResult = RestCallAnyWhere::call($appendCall);
        }

        RestHttpResponse::json($arrResult);
   }

    /**
     * @RequestMapping(value="/actions/delete", method="POST")
     */
    public function delete() {
        $form = RestHttpRequest::getBody(FileDeleteForm::class, true);

        //一级配置检查.
        self::deleteFile($form->getUrl());
    }

    /**
     * 删除文件.
     * @param $visitPath
     */
    public static function deleteFile($visitPath) {
        //一级配置检查.
        $arrConfig = $GLOBALS[RestUploadConstant::UPLOAD_CONFIG_NAME];
        $rootDir = $arrConfig[RestUploadConstant::UPLOAD_CONFIG_NAME_SAVE_ROOT];

        // 文件真实路径.
        $filePath = $rootDir . $visitPath;

        if (file_exists($filePath)) {
            @unlink($filePath);
        }
    }
}